/**
 * Project of Vehicle Routing Problem with Time Windows implements 
 * some of well-known algorithms for solving VRPTW and presents new 
 * one.
 *
 * @author Michal Drobny  
 */

package logic.evaluator;

import logic.destination.Destination;
import logic.restriction.interfaces.HasLocation;
import logic.route.Cycle;

/**
 * Represents the Euclidean evaluator. Assigns a value to the path between two
 * destinations. The value is calculated as an euclidean distance from the axis
 * of given destinations.
 * 
 * @author Michal Drobny
 * @date 2.10.2014
 */
public class EuclideanEvaluator implements Evaluator {

	/**
	 * Contructor.
	 */
	public EuclideanEvaluator() {
	}

	@Override
	public double evaluate(Destination first, Destination second) {
		
		if (first == null || second == null)
			return -1d;
		
		if (!(first instanceof HasLocation) || !(second instanceof HasLocation))
			return -1d;

		HasLocation firstLoc = (HasLocation) first;
		HasLocation secondLoc = (HasLocation) second;
		
		if (firstLoc.getLocation() == null || secondLoc.getLocation() == null)
			return -1d;
		
		return firstLoc.getLocation().getDistanceTo(secondLoc.getLocation());
	}

	@Override
	public double evaluate(Cycle cycle) {
		
		if (cycle == null || cycle.getDestinations() == null)
			return -1;
		
		if (cycle.getDestinations().isEmpty())
			return 0d;
		
		double sum = 0d;
		Destination start = cycle.getDestinations().get(0);
		for (int i = 1; i < cycle.getDestinations().size(); ++i) {
			double value = evaluate(start, cycle.getDestinations().get(i));
			if (value == -1d)
				return -1d;
			else
				sum += value;
		}
		
		double value = evaluate(cycle.getDestinations().get(cycle.getDestinations().size()-1), start);
		if (value == -1d)
			return -1d;
		else
			sum += value;
			
		return sum;
	}
}